Skip to content

Add BitMap component (#10110) - #12360

Merged
msynk merged 31 commits into
bitfoundation:developfrom
msynk:10110-blazorui-map-component
May 29, 2026
Merged

Add BitMap component (#10110)#12360
msynk merged 31 commits into
bitfoundation:developfrom
msynk:10110-blazorui-map-component

Conversation

@msynk

@msynk msynk commented May 18, 2026

Copy link
Copy Markdown
Member

closes #10110

Summary by CodeRabbit

  • New Features

    • New interactive Map component with many pluggable providers (Leaflet, MapLibre, Mapbox, OpenLayers, ArcGIS, Azure Maps, Cesium 3D) plus rich runtime APIs (markers, drag/click, popups/tooltips, vectors, GeoJSON, tile overlays, view/navigation controls, provider swapping).
  • Documentation / Demos

    • Added comprehensive demo page with 13 examples, usage snippets and a Map nav item.
  • Style

    • New map stylesheet and bundled Leaflet CSS.
  • Tests

    • New bUnit test suite covering lifecycle, interop and behaviors.
  • Chores

    • Updated root .gitignore; ensured specific component CSS remains tracked.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f96e422e-47bb-40ba-b134-e8b6e42abc92

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a provider-pluggable Blazor BitMap component with C# models/contracts, IJSRuntime extensions, multiple TypeScript map providers (Leaflet, MapLibre/Mapbox GL, OpenLayers, Cesium, ArcGIS, Azure), an OpenLayers loader, bundled Leaflet CSS, SCSS styles, demo pages, navigation, and bUnit tests.

Changes

BitMap Component

Layer / File(s) Summary
Component, interop, and lifecycle
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor, src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor.cs, src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapJsRuntimeExtensions.cs
New generic BitMap<TMapProvider> component implementing provider selection, asset loading, JS interop init/sync/dispose, imperative APIs, JS-invokable callbacks, provider swapping with optional state replay, and safe interop error reporting.
Public contracts and validation
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/*LatLng*.cs, BitMapLatLngBounds.cs, BitMapMarker*.cs, BitMapViewState.cs, BitMapTileOverlay.cs, BitMapVectorPathStyle.cs, IBitMapProvider.cs, BitMapProviderBase.cs, BitMapValidation.cs, BitMapInteropErrorArgs.cs, BitMapTooltipDirection.cs
New typed contracts and helper validation for coordinates, bounds (antimeridian-aware), markers, view snapshots, tile overlays, vector styles, provider interface/base, and interop error payloads.
JS runtime extensions
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapJsRuntimeExtensions.cs
IJSRuntime extension methods standardizing calls to BitBlazorUI.<jsObjectName>.* for lifecycle, view, marker, vector, GeoJSON, and tile overlay operations.
Shared JS helpers & OpenLayers loader
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapShared.ts, src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/openlayers/bit-map-ol-loader.js
Shared JS utilities (hex→rgba, circle ring, style normalization, global wait/resolve) and a CSP-friendly OpenLayers ES module loader exposed as globalThis.__bitMapOlBundle.
Provider JS/TS implementations
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/*
Multiple provider implementations: Leaflet, GL-based base (BitMapGlBase) with MapLibre/Mapbox wrappers, OpenLayers, Cesium, ArcGIS, Azure Maps; each implements init/sync/dispose, markers, vectors, GeoJSON, tile overlays, and event routing.
C# provider types & base
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/*MapProvider.cs, BitMapProviderBase.cs
C# provider classes that surface provider-specific options and BuildOptionsPayload implementations; provider-base centralizes common options and validation helpers.
Styles & assets
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.scss, src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss, src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/leaflet-1.9.4.css
Component SCSS (container, canvas, overlay, OpenLayers popup styles), SCSS import added to extras, and bundled Leaflet 1.9.4 CSS asset.
Demo & navigation
src/BlazorUI/Demo/Client/.../BitMapDemo.razor, BitMapDemo.razor.cs, MainLayout.razor.NavItems.cs
New demo page with 13 examples across providers, and navigation entry under Extras.
Tests
src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/Map/BitMapTests.cs
bUnit tests for lifecycle, asset dedupe, provider swap/replay, validation, idempotent disposal, and interop-error swallowing.
Repo config
.gitignore
Ignore rules for root-level .kiro/#kiro and .cursor/#cursor; negation added to keep Leaflet CSS under wwwroot/leaflet/*.css tracked.

Sequence Diagram(s)

sequenceDiagram
  participant Blazor as BitMap (C#)
  participant JSRuntime as IJSRuntime
  participant ProviderJS as BitBlazorUI.<jsObject>
  participant MapLib as Map library

  Blazor->>JSRuntime: BitMapInit(jsObjectName, id, canvasId, element, dotnetRef, options)
  JSRuntime->>ProviderJS: init(id, canvasId, element, dotnetRef, options)
  ProviderJS->>MapLib: create map, add layers, attach events
  ProviderJS-->>Blazor: OnReady / OnViewChanged / OnClick callbacks
  Blazor->>JSRuntime: BitMapAddMarker / BitMapSync / BitMapDispose
  JSRuntime->>ProviderJS: corresponding method(id, ...)
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Poem

"I hopped to the map with a twitch of my nose,
Scripts, styles, and providers in tidy rows.
Markers and vectors, a demo to show,
Leaflet and Cesium where brave bunnies go.
🐰🌱 — signed, the BitRabbit"

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a new generic, provider-pluggable BitMap<TMapProvider> component in Bit.BlazorUI.Extras with seven map backends (Leaflet, MapLibre GL, Mapbox GL, OpenLayers, ArcGIS, Azure Maps, Cesium), exposing a unified imperative API for markers, vector layers, GeoJSON, tile overlays, and view manipulation, plus a full demo page. Closes #10110.

Changes:

  • Adds BitMap Razor component, supporting types (BitMapLatLng, Bounds, Marker, VectorPathStyle, TileOverlay, ViewState, callback args), IBitMapProvider/BitMapProviderBase, and concrete provider classes for each backend.
  • Adds the corresponding TypeScript providers (BitMapLeaflet, BitMapGlBase + MapLibre/Mapbox wrappers, BitMapOpenLayers, BitMapArcGis, BitMapAzureMaps, BitMapCesium) plus shared helpers, and wires SCSS via extra-components.scss.
  • Registers the demo page, navigation entry, JS interop extensions, and ignores .kiro/.cursor editor folders.

Reviewed changes

Copilot reviewed 33 out of 40 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor[.cs] New generic component + imperative API and JSInvokable bridge methods.
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap{LatLng,LatLngBounds,Marker,TileOverlay,VectorPathStyle,ViewState,MarkerDragEndArgs}.cs Shared domain types/payloads.
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/IBitMapProvider.cs, BitMapProviderBase.cs Provider abstraction and common options.
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/Bit*MapProvider.cs Seven concrete C# provider configurations.
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMap*.ts TypeScript runtime adapters (Leaflet, GL base + MapLibre/Mapbox, OpenLayers, ArcGIS, AzureMaps, Cesium, shared helpers).
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapJsRuntimeExtensions.cs Provider-agnostic JS interop helpers.
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.scss + Styles/extra-components.scss Component styles and aggregator.
src/BlazorUI/Demo/.../Pages/Components/Extras/Map/BitMapDemo.razor[.cs] Demo page with 13 examples covering all providers.
src/BlazorUI/Demo/.../Shared/MainLayout.razor.NavItems.cs Adds "Map" entry to demo nav.
.gitignore Ignores .kiro and .cursor editor directories.
Comments suppressed due to low confidence (1)

src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapOpenLayers.ts:156

  • AddMarker first adds the new feature to s.markerSource, then checks if a marker with the same id already exists and removes it. Because the new feature has just been registered with the same id (f.setId(markerId)), s.markerSource.addFeature(f) may throw an "AssertionError: Feature already added to the source" before the previous entry is cleaned up. Remove s.markers[markerId] from the source before adding the new feature, mirroring the pattern used in the other providers.
            f.setId(markerId);
            f.setStyle(BitMapOpenLayers._markerStyle(ol, opts));
            s.markerSource.addFeature(f);
            const existing = s.markers[markerId];
            if (existing) try { s.markerSource.removeFeature(existing); } catch { /* ignore */ }
            s.markers[markerId] = f;
        }

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapOpenLayers.ts Outdated
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapAzureMaps.ts Outdated
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapGlBase.ts Outdated
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapCesium.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

🧹 Nitpick comments (1)
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor (1)

203-203: ⚡ Quick win

Add explicit labels for token/key fields.

Line 203 and Line 233 currently rely on placeholders only. Add Label to improve screen-reader clarity and form accessibility.

Proposed change
-            <BitTextField `@bind-Value`="mapboxToken" Placeholder="pk.eyJ1…" Style="margin-bottom:0.5rem;max-width:480px" />
+            <BitTextField Label="Mapbox access token" `@bind-Value`="mapboxToken" Placeholder="pk.eyJ1…" Style="margin-bottom:0.5rem;max-width:480px" />
...
-            <BitTextField `@bind-Value`="azureMapsKey" Placeholder="Azure Maps subscription key" Style="margin-bottom:0.5rem;max-width:480px" />
+            <BitTextField Label="Azure Maps subscription key" `@bind-Value`="azureMapsKey" Placeholder="Azure Maps subscription key" Style="margin-bottom:0.5rem;max-width:480px" />

Also applies to: 233-233

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor`
at line 203, Add explicit Label attributes to the BitTextField components that
currently only use Placeholder so screen readers can announce them; locate the
BitTextField instances bound to mapboxToken (BitTextField
`@bind-Value`="mapboxToken") and the other token/key field around the second
occurrence (the BitTextField at line ~233) and add a meaningful Label (e.g.,
Label="Mapbox token" and Label="MapTiler key") to each component so they are
accessible to assistive tech.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor.cs`:
- Around line 302-308: OnProviderSet currently returns early when Provider is
null, which prevents reverting to a default provider after initialization;
change OnProviderSet so that when _initialized is true and Provider is null you
create/assign a default TMapProvider (or call ProviderFactory/default factory)
and proceed to call _js.BitMapSync(JsObject, _Id,
Provider.BuildOptionsPayload()) and set _activeProvider = Provider; ensure the
logic still skips work only when nothing changed (e.g., _activeProvider equals
Provider) but handles the "post-init reset to null" case by reinstating the
default provider and resending options.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.scss`:
- Around line 9-13: The CSS rule for .bit-map-canvas removes the browser focus
outline (outline: none), which hides keyboard focus for the focusable map
canvas; restore visible keyboard focus by removing the outline: none declaration
(or replace it with a sensible focus style such as outline: auto or add a
:focus/:focus-visible rule to provide an accessible focus ring) so that the
.bit-map-canvas element shows a clear focus indicator when tabbed to.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitArcGisMapProvider.cs`:
- Around line 35-41: In BuildOptionsPayload, validate the basemap/key combo
before returning the payload: if BasemapId is not "osm" (case-insensitive) and
ApiKey is null/empty, throw a clear ArgumentException (or
InvalidOperationException) with a message explaining that non‑OSM basemaps
require a valid ApiKey; use the existing GetCommonOptions(), BasemapId and
ApiKey symbols to locate where to add the check so invalid combinations fail
fast rather than emitting a runtime JS config error.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitAzureMapsMapProvider.cs`:
- Around line 10-37: The SubscriptionKey property is required but currently can
be empty and is passed into BuildOptionsPayload; update the BuildOptionsPayload
method in BitAzureMapsMapProvider to validate SubscriptionKey
(non-empty/non-whitespace) and throw a clear exception (e.g., ArgumentException)
if it's missing before calling GetCommonOptions; then only add
common["subscriptionKey"] = SubscriptionKey after validation so initialization
fails fast and provides a deterministic error.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts`:
- Around line 232-267: addGeoJson currently only handles Point, LineString, and
Polygon and silently drops MultiPoint, MultiLineString, MultiPolygon and
GeometryCollection; update addGeoJson to recursively expand multi-geometries and
GeometryCollection into their constituent geometries and create graphics for
each piece using the same attribute merge (props) and existing symbol helpers
(_lineSym, _fillSym, Point symbol); for MultiPoint create a Graphic per
coordinate using esri.Point, for MultiLineString create a Polyline per
coordinate array, for MultiPolygon create one or more Polygon graphics using
rings (maintaining spatialReference { wkid: 4326 }), and for GeometryCollection
iterate its geometries and dispatch by type; keep using esri.Graphic and ensure
all created graphics are added to s.view.graphics and included in
s.geoJsonLayers[layerId] so nothing is silently dropped.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapAzureMaps.ts`:
- Around line 265-296: When adding a GeoJSON/vector layer (in addGeoJson and the
similar _addVectorLayer code paths referenced around lines 344-356) we currently
overwrite s.geoJsonLayers[layerId] without removing the previously-added map
layers and source, leaking stale layers; update both functions to first check
s.geoJsonLayers[layerId], and if present iterate its layerIds to remove each
layer from s.map.layers (s.map.layers.remove(...)) and remove the previous
source from s.map.sources (and dispose/clear the DataSource if appropriate),
then delete the registry entry before creating and registering the new
DataSource and layers so removeLayer will correctly clean up the latest
instance.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapboxMapProvider.cs`:
- Around line 10-41: The BuildOptionsPayload currently forwards StyleUrl and
AccessToken unchanged which allows a "mapbox://" style to be used with an empty
AccessToken; update BitMapboxMapProvider.BuildOptionsPayload to validate and
guard this: detect when StyleUrl starts with "mapbox://" and if
string.IsNullOrWhiteSpace(AccessToken) either throw a clear ArgumentException
(or return/fallback to a non-mapbox CDN style) so consumers get a deterministic
failure instead of runtime errors; modify the method to check
StyleUrl.StartsWith("mapbox://", StringComparison.OrdinalIgnoreCase) and handle
the empty AccessToken case before adding values to the common dictionary.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapCesium.ts`:
- Around line 258-273: addGeoJson only sets _bmLayerId on the DataSource, but
the click handler expects metadata on each picked Entity, so GeoJSON features
never trigger OnGeoJsonFeatureClick; update BitMapCesium.addGeoJson (and the
similar routine around lines 381-395) to iterate ds.entities.values and for each
entity set entity._bmLayerId = layerId and entity._bmKind = 'geojson' (or
whatever kind the click handler checks), and also apply any per-entity
style/metadata as needed so the pick logic can detect GeoJSON features; keep the
existing DataSource tagging but ensure every Entity gets the same metadata after
GeoJsonDataSource.load completes and before adding to viewer.
- Around line 150-160: The add/remove order is reversed causing Cesium to throw
on duplicate IDs; locate the marker creation blocks (uses s.viewer.entities.add,
id `bm-marker-${id}-${markerId}`, variables ent, existing and
s.markers[markerId]) and remove any existing entity first (check existing =
s.markers[markerId]; if (existing) try { s.viewer.entities.remove(existing); }
catch {/*ignore*/}) before calling s.viewer.entities.add(...) and then assign
s.markers[markerId] = ent; apply the same change to the other similar blocks
referenced (around the ranges mentioned).

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapGlBase.ts`:
- Around line 292-297: The click handlers attached via s.map.on('click', ...)
(the handler created near lines with layerId/fillId/lineId) are never
unregistered, so update the code to store these handler references in the
vectorCatalog entry for the vector (e.g., keep the handler function(s) under
vectorCatalog[layerId].clickHandler or similar) and then, inside _removeVector,
call s.map.off('click', fillId, handler) and s.map.off('click', lineId, handler)
(or the exact stored handler refs) before removing the layers and source; ensure
you reference the same handler function objects when calling map.off so
listeners are fully removed and will not persist when layers are re-added.
- Line 177: The popup content is being injected unsafely via
setHTML(String(opts.popupHtml)) in BitMapGlBase; guard against XSS by checking
the source and type of opts.popupHtml and either (a) use marker.setPopup(new
gl.Popup({ offset: 25 }).setText(String(opts.popupHtml))) for
untrusted/plain-text input or (b) run opts.popupHtml through a
sanitizer/whitelist before calling setHTML; update the code path that constructs
the Popup in BitMapGlBase to choose setText when content is untrusted or
sanitize/validate the HTML first and only call setHTML when it is known-safe.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapOpenLayers.ts`:
- Around line 34-48: The provider never maps public interaction toggles
(scrollWheelZoom, dragging, doubleClickZoom, keyboardNavigation) into
OpenLayers, so update the ol.Map creation and the sync path to pass and toggle
ol.interaction.defaults based on the component options object (o) — e.g., set
the map option interactions: ol.interaction.defaults({mouseWheelZoom:
o.scrollWheelZoom !== false, dragPan: o.dragging !== false, doubleClickZoom:
o.doubleClickZoom !== false, keyboard: o.keyboardNavigation !== false}) when
constructing the map in init, and in sync (or the equivalent update handler)
enable/disable those interactions on the existing map instance (map) to reflect
changes to o.scrollWheelZoom, o.dragging, o.doubleClickZoom, and
o.keyboardNavigation.
- Around line 230-238: The style function styleFn currently returns ol.Style({
stroke, fill }) for Point and MultiPoint geometries which doesn't render points;
update styleFn to check for 'Point' and 'MultiPoint' types and return an
ol.Style that includes an image (e.g., ol.style.Circle with radius, fill/stroke)
alongside stroke/fill so point features render; modify the branch where you
create new ol.Style({ stroke, fill }) to instead create new ol.Style({ image: /*
Circle style using fill/stroke */, stroke, fill }) ensuring compatibility with
ol.VectorLayer and the existing features variable.

---

Nitpick comments:
In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor`:
- Line 203: Add explicit Label attributes to the BitTextField components that
currently only use Placeholder so screen readers can announce them; locate the
BitTextField instances bound to mapboxToken (BitTextField
`@bind-Value`="mapboxToken") and the other token/key field around the second
occurrence (the BitTextField at line ~233) and add a meaningful Label (e.g.,
Label="Mapbox token" and Label="MapTiler key") to each component so they are
accessible to assistive tech.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7aaa1a15-5612-413b-a9bd-8deefa307b2b

📥 Commits

Reviewing files that changed from the base of the PR and between 282ce86 and 1c01bc3.

⛔ Files ignored due to path filters (5)
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/layers-2x.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/layers.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-icon-2x.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-icon.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-shadow.png is excluded by !**/*.png
📒 Files selected for processing (35)
  • .gitignore
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLng.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLngBounds.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarker.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarkerDragEndArgs.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapProviderBase.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapTileOverlay.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapVectorPathStyle.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapViewState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/IBitMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitArcGisMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitAzureMapsMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitCesiumMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitLeafletMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapAzureMaps.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapCesium.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapGlBase.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapLeaflet.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapLibreMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapMapLibre.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapMapbox.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapOpenLayers.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapShared.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapboxMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitOpenLayersMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/leaflet-1.9.4.js
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/MainLayout.razor.NavItems.cs

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor.cs
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.scss
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapGlBase.ts Outdated
@msynk
msynk requested a review from Copilot May 18, 2026 09:23
@msynk

msynk commented May 18, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

@msynk Sure, I'll re-review the PR now.

✅ Actions performed

Full review triggered.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 33 out of 40 changed files in this pull request and generated 3 comments.

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts Outdated
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor.cs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

♻️ Duplicate comments (2)
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapboxMapProvider.cs (1)

34-41: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add a null/empty guard for StyleUrl before StartsWith.

Line 36 can throw if StyleUrl is null at runtime. Validate it first and fail with a deterministic message.

Suggested fix
 public override object BuildOptionsPayload()
 {
+    if (string.IsNullOrWhiteSpace(StyleUrl))
+    {
+        throw new InvalidOperationException("BitMapboxMapProvider: StyleUrl is required.");
+    }
+
     if (StyleUrl.StartsWith("mapbox://", StringComparison.OrdinalIgnoreCase) && string.IsNullOrWhiteSpace(AccessToken))
     {
         throw new InvalidOperationException(
             $"BitMapboxMapProvider: An AccessToken is required when using a 'mapbox://' style ('{StyleUrl}'). " +
             "Provide a valid Mapbox access token or use a non-Mapbox style URL.");
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapboxMapProvider.cs`
around lines 34 - 41, In BuildOptionsPayload, guard against null/empty StyleUrl
before calling StyleUrl.StartsWith to avoid a NullReferenceException: check
string.IsNullOrWhiteSpace(StyleUrl) first and throw a clear
InvalidOperationException (similar to the existing AccessToken check) when
StyleUrl is null/empty; only then evaluate StartsWith("mapbox://",
StringComparison.OrdinalIgnoreCase) and proceed with the current AccessToken
validation (reference: BuildOptionsPayload, StyleUrl, AccessToken).
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitArcGisMapProvider.cs (1)

37-42: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Harden BasemapId validation and make OSM check case-insensitive.

Line 37 treats "OSM" as non-OSM and may enforce ApiKey incorrectly. Also guard empty BasemapId early.

Suggested fix
 public override object BuildOptionsPayload()
 {
-    if (BasemapId is not "osm" && string.IsNullOrWhiteSpace(ApiKey))
+    if (string.IsNullOrWhiteSpace(BasemapId))
+    {
+        throw new InvalidOperationException("BitArcGisMapProvider: BasemapId is required.");
+    }
+
+    if (!string.Equals(BasemapId, "osm", StringComparison.OrdinalIgnoreCase) && string.IsNullOrWhiteSpace(ApiKey))
     {
         throw new InvalidOperationException(
             $"BitArcGisMapProvider: An ApiKey is required for the '{BasemapId}' basemap. " +
             "Only the 'osm' basemap works without an API key.");
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitArcGisMapProvider.cs`
around lines 37 - 42, Validate BasemapId in BitArcGisMapProvider by first
guarding against null/empty/whitespace (throwing a clear
InvalidOperationException if missing), then perform the OSM check using a
case-insensitive comparison (e.g., compare BasemapId to "osm" with
StringComparison.OrdinalIgnoreCase or normalize with ToLowerInvariant/Trim) so
values like "OSM" or extra whitespace don't incorrectly require an ApiKey, and
only throw the existing ApiKey-required InvalidOperationException when the
normalized BasemapId is not "osm" and ApiKey is null/whitespace.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapVectorPathStyle.cs`:
- Around line 14-22: The Opacity and FillOpacity properties on
BitMapVectorPathStyle accept any double but are documented as 0–1; clamp their
values to the valid range by implementing bounded setters for Opacity and
FillOpacity (or validate and clamp right before serialization) so any assigned
value <0 becomes 0 and >1 becomes 1; update the property implementations on the
BitMapVectorPathStyle class (the Opacity and FillOpacity members) to enforce
this clamping and preserve existing defaults.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitCesiumMapProvider.cs`:
- Around line 65-82: In BuildOptionsPayload, enforce Cesium token-dependent
options before returning the payload: check IonAccessToken (in
BuildOptionsPayload) and if it's null/empty disable token-required features (set
TerrainEnabled to false and override any Bing/ion-dependent ImageryStyle to a
safe default) so the payload never enables terrain or Bing imagery when
IonAccessToken is missing; update the logic around the TerrainEnabled,
ImageryStyle and IonAccessToken assignments in BuildOptionsPayload accordingly.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts`:
- Around line 64-72: BitMapArcGis.sync currently updates
center/zoom/basemap/scale but doesn't reapply interaction flags (e.g.,
scrollWheelZoom, dragging) that init sets, so update BitMapArcGis.sync to read
the same options (o.scrollWheelZoom, o.dragging or their exact names used in
init) and reapply them to the stored map/view instance s (the same
enable/disable logic used in BitMapArcGis.init), ensuring interaction state is
toggled on s.view or s.map the same way as during initialization; reference
BitMapArcGis.sync, BitMapArcGis.init, BitMapArcGis._maps and
BitMapArcGis._ensureScaleBar when making the change.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapAzureMaps.ts`:
- Around line 318-327: The addTileOverlay implementation
(BitMapAzureMaps.addTileOverlay) currently overwrites s.tileOverlays[opts.id]
without removing any previous layer; before creating the new TileLayer (tlId),
check s.tileOverlays[opts.id] for an existing layer id, locate that layer in
s.map.layers (by the stored layer id) and remove it from the map (and from the
registry) so you don't leave stale state, then proceed to create and add the new
TileLayer and set s.tileOverlays[opts.id] = tlId.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapCesium.ts`:
- Around line 133-143: The SetView and FlyTo methods always default zoom to 4,
causing unintended zoom changes when zoom is omitted; change them to preserve
the current camera altitude when zoom is null by reading the current camera
height (e.g. from s.viewer.camera.positionCartographic.height or equivalent) and
only call BitMapCesium._zoomToAltitude when zoom is provided. Update both
BitMapCesium.setView and BitMapCesium.flyTo to compute altitude = zoom != null ?
BitMapCesium._zoomToAltitude(zoom) : currentCameraHeight and use that altitude
for Cesium.Cartesian3.fromDegrees.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapGlBase.ts`:
- Around line 328-344: The addTileOverlay method currently returns early when a
source already exists, so new URL/opacity/maxZoom aren't applied; modify
addTileOverlay (and use the instance from BitMapGlBase._require) to detect
existing tileOverlayCatalog[opts.id] or s.map.getSource(sourceId) and remove the
old layer and source (s.map.removeLayer(layerId) and
s.map.removeSource(sourceId)) before adding the new source and layer, or
alternatively update the existing layer's paint and source options via
s.map.setPaintProperty and by recreating the source with the new tiles/maxzoom;
ensure you keep tileOverlayCatalog[opts.id] in sync with the new
sourceId/layerId after replacing/updating so subsequent calls reflect the new
URL/opacity/maxZoom.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapLeaflet.ts`:
- Around line 90-93: The sync currently forces a hardcoded center by building c
= [o.center?.lat ?? 51.505, o.center?.lng ?? -0.09] and always calling
s.map.setView(c, z), which can jump the map on option-only updates; change sync
so it only calls s.map.setView when options.center is explicitly provided (use
o.center and o.zoom or fall back to current s.map.getZoom for the z argument),
and if only options.zoom is provided call s.map.setZoom(o.zoom, { animate: false
}) instead of rebuilding a default center; reference variables/methods:
function/method sync in BitMapLeaflet.ts, variables o.center, o.zoom, c, z, and
calls s.map.setView / s.map.setZoom.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapOpenLayers.ts`:
- Line 181: BitMapOpenLayers.openMarkerPopup currently silently no-ops; change
it to surface a clear failure by throwing a descriptive Error (or at minimum
logging and throwing) so caller code knows OpenLayers doesn't support this
built-in popup behavior; update the method BitMapOpenLayers.openMarkerPopup to
throw an Error that includes context (the passed _id and _markerId and that
OpenLayers requires a custom overlay/implementation) so provider-agnostic
callers receive a visible failure instead of silent no-op.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapShared.ts`:
- Around line 45-53: The circleRingLngLat function can divide by points causing
NaN when points <= 0; add a guard at the start of circleRingLngLat to validate
and normalize points (e.g., if points is not a positive integer, set points =
Math.max(1, Math.floor(points)) or throw a clear error) before using it in the
bearing calculation and loop; ensure the rest of the function uses the
normalized points variable so the division (bearing = (i / points) * 2 *
Math.PI) and loop bounds are safe.

---

Duplicate comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitArcGisMapProvider.cs`:
- Around line 37-42: Validate BasemapId in BitArcGisMapProvider by first
guarding against null/empty/whitespace (throwing a clear
InvalidOperationException if missing), then perform the OSM check using a
case-insensitive comparison (e.g., compare BasemapId to "osm" with
StringComparison.OrdinalIgnoreCase or normalize with ToLowerInvariant/Trim) so
values like "OSM" or extra whitespace don't incorrectly require an ApiKey, and
only throw the existing ApiKey-required InvalidOperationException when the
normalized BasemapId is not "osm" and ApiKey is null/whitespace.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapboxMapProvider.cs`:
- Around line 34-41: In BuildOptionsPayload, guard against null/empty StyleUrl
before calling StyleUrl.StartsWith to avoid a NullReferenceException: check
string.IsNullOrWhiteSpace(StyleUrl) first and throw a clear
InvalidOperationException (similar to the existing AccessToken check) when
StyleUrl is null/empty; only then evaluate StartsWith("mapbox://",
StringComparison.OrdinalIgnoreCase) and proceed with the current AccessToken
validation (reference: BuildOptionsPayload, StyleUrl, AccessToken).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5edad8b8-6807-4608-8452-a84d84564da4

📥 Commits

Reviewing files that changed from the base of the PR and between 282ce86 and 3f0880d.

⛔ Files ignored due to path filters (5)
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/layers-2x.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/layers.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-icon-2x.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-icon.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-shadow.png is excluded by !**/*.png
📒 Files selected for processing (35)
  • .gitignore
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLng.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLngBounds.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarker.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarkerDragEndArgs.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapProviderBase.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapTileOverlay.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapVectorPathStyle.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapViewState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/IBitMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitArcGisMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitAzureMapsMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitCesiumMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitLeafletMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapAzureMaps.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapCesium.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapGlBase.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapLeaflet.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapLibreMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapMapLibre.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapMapbox.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapOpenLayers.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapShared.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapboxMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitOpenLayersMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/leaflet-1.9.4.js
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/MainLayout.razor.NavItems.cs

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapVectorPathStyle.cs Outdated
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapLeaflet.ts Outdated
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapOpenLayers.ts Outdated
@msynk
msynk requested a review from Copilot May 18, 2026 10:33
@msynk

msynk commented May 18, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

@msynk Sure, I'll re-review the PR now.

✅ Actions performed

Full review triggered.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 33 out of 40 changed files in this pull request and generated 8 comments.

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarkerDragEndArgs.cs Outdated
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor.cs Outdated
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapOpenLayers.ts Outdated
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapGlBase.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (1)
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapboxMapProvider.cs (1)

34-37: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add a null/empty guard for StyleUrl before StartsWith.

StartsWith on a null StyleUrl causes an immediate runtime failure instead of a clear configuration error.

Proposed fix
 public override object BuildOptionsPayload()
 {
+    if (string.IsNullOrWhiteSpace(StyleUrl))
+    {
+        throw new InvalidOperationException("BitMapboxMapProvider: StyleUrl is required.");
+    }
+
     if (StyleUrl.StartsWith("mapbox://", StringComparison.OrdinalIgnoreCase) && string.IsNullOrWhiteSpace(AccessToken))
     {
         throw new InvalidOperationException(
             $"BitMapboxMapProvider: An AccessToken is required when using a 'mapbox://' style ('{StyleUrl}'). " +
             "Provide a valid Mapbox access token or use a non-Mapbox style URL.");
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapboxMapProvider.cs`
around lines 34 - 37, In BuildOptionsPayload(), guard StyleUrl for null/empty
before calling StyleUrl.StartsWith(...) — e.g., check
string.IsNullOrWhiteSpace(StyleUrl) first and handle it (throw a clear
configuration exception or return an appropriate error) so the subsequent
StartsWith call is never invoked on null; also retain the existing AccessToken
check and ensure the error message references StyleUrl and AccessToken for
clarity.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitCesiumMapProvider.cs`:
- Around line 67-77: The code treats whitespace-only IonAccessToken as present;
update the token presence check in the BitCesiumMapProvider by replacing
string.IsNullOrEmpty(IonAccessToken) with
string.IsNullOrWhiteSpace(IonAccessToken) (i.e., compute hasToken =
!string.IsNullOrWhiteSpace(IonAccessToken)) so TerrainEnabled/terrainEnabled and
imageryStyle logic correctly treat whitespace tokens as missing, and ensure
common["ionAccessToken"] is only set when hasToken is true (otherwise leave it
null/empty).

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitLeafletMapProvider.cs`:
- Around line 20-21: The TileOpacity property on BitLeafletMapProvider currently
allows any double but is documented as 0–1; update the TileOpacity property
setter (the TileOpacity auto-property) to clamp incoming values to the [0,1]
range (e.g., set to 0 if value < 0, to 1 if value > 1, otherwise keep value) so
the component honors its documented contract and use that clamped value
internally when raising any change notifications or rendering updates.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts`:
- Around line 323-335: In addTileOverlay (BitMapArcGis.addTileOverlay) remove
any existing tile layer from s.tileOverlays[opts.id] (and call s.map.remove on
it) before creating/adding the new esri.WebTileLayer; use
BitMapArcGis._require(id) to get s, check const existing =
s.tileOverlays[opts.id] and if present call s.map.remove(existing) and clear
s.tileOverlays[opts.id] before instantiating tl and calling s.map.add(tl), then
assign s.tileOverlays[opts.id] = tl.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitOpenLayersMapProvider.cs`:
- Around line 19-20: TileOpacity currently allows values outside the documented
0–1 range; change the auto-property to use a private backing field and clamp
assignments in the TileOpacity setter (e.g., use Math.Clamp(value, 0.0, 1.0)) so
any set (including the default) is constrained to 0..1 and keep the default at
1.0; update references to the property if they relied on direct field access.

---

Duplicate comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapboxMapProvider.cs`:
- Around line 34-37: In BuildOptionsPayload(), guard StyleUrl for null/empty
before calling StyleUrl.StartsWith(...) — e.g., check
string.IsNullOrWhiteSpace(StyleUrl) first and handle it (throw a clear
configuration exception or return an appropriate error) so the subsequent
StartsWith call is never invoked on null; also retain the existing AccessToken
check and ensure the error message references StyleUrl and AccessToken for
clarity.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 581b08e6-756e-448c-8bbc-f77f5a867969

📥 Commits

Reviewing files that changed from the base of the PR and between 282ce86 and 478dcbf.

⛔ Files ignored due to path filters (5)
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/layers-2x.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/layers.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-icon-2x.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-icon.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-shadow.png is excluded by !**/*.png
📒 Files selected for processing (35)
  • .gitignore
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLng.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLngBounds.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarker.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarkerDragEndArgs.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapProviderBase.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapTileOverlay.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapVectorPathStyle.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapViewState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/IBitMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitArcGisMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitAzureMapsMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitCesiumMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitLeafletMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapAzureMaps.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapCesium.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapGlBase.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapLeaflet.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapLibreMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapMapLibre.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapMapbox.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapOpenLayers.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapShared.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapboxMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitOpenLayersMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/leaflet-1.9.4.js
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/MainLayout.razor.NavItems.cs

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitCesiumMapProvider.cs Outdated
@msynk
msynk requested a review from Copilot May 19, 2026 09:29
@msynk

msynk commented May 19, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown

@msynk Sure, I'll re-review the PR now.

✅ Actions performed

Full review triggered.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 33 out of 40 changed files in this pull request and generated no new comments.

@msynk
msynk requested a review from Copilot May 27, 2026 19:51
@msynk

msynk commented May 27, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown

@msynk Sure, I'll re-review the PR now.

✅ Actions performed

Full review triggered.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

♻️ Duplicate comments (3)
src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss (1)

7-7: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remove .scss extension from the Sass import.

Line 7 currently violates scss/load-partial-extension and can fail linting.

🔧 Suggested fix
-@import "../Components/Map/BitMap.scss";
+@import "../Components/Map/BitMap";
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss` at line 7, The
Sass import in extra-components.scss uses a filename with the .scss extension
which violates scss/load-partial-extension; update the import statement that
currently references "../Components/Map/BitMap.scss" to omit the .scss extension
(use "../Components/Map/BitMap") so the linter accepts the partial import.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor.cs (1)

772-804: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep example7CsharpCode aligned with the real overlay-reset behavior.

The live BuildAdvancedProvider() resets advOverlayOn, but the displayed snippet doesn’t; copied sample code can leave the toggle state out of sync after provider rebuilds.

🧩 Suggested snippet fix
 private BitLeafletMapProvider BuildAdvancedProvider()
 {
     advProvider = new BitLeafletMapProvider
     {
         Center = new(51.5074, -0.1278), Zoom = 11,
         ScrollWheelZoom = advScrollWheel,
         Dragging = advDragging,
         ShowScaleControl = advScaleBar,
         MaxBounds = advMaxBounds
             ? new BitMapLatLngBounds(new(51.25, -0.55), new(51.75, 0.35))
             : null,
     };
+    advOverlayOn = false;
     return advProvider;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor.cs`
around lines 772 - 804, The sample string example7CsharpCode is out of sync with
the real BuildAdvancedProvider behavior because the live BuildAdvancedProvider
resets advOverlayOn when rebuilding the provider but the displayed snippet does
not; update the example7CsharpCode snippet to show the same reset logic by
modifying the BuildAdvancedProvider code in the snippet to set advOverlayOn =
false (or the real reset behavior) when creating the new advProvider, ensuring
the displayed BuildAdvancedProvider matches the runtime method and keeps
advOverlayOn consistent after provider rebuilds.
src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor (1)

3-5: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Polish the PageOutlet description text.

The current text is grammatically awkward and uses inconsistent casing.

✏️ Suggested fix
 <PageOutlet Url="components/map"
             Title="Map"
-            Description="map component of the bit BlazorUI components" />
+            Description="Map component for Bit BlazorUI components." />
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor`
around lines 3 - 5, Update the PageOutlet component's Description attribute to a
polished, grammatically correct string: replace Description="map component of
the bit BlazorUI components" with a properly cased sentence such as
Description="Map component of the Bit BlazorUI components." (edit the PageOutlet
element where Url="components/map" and Title="Map").
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLngBounds.cs`:
- Around line 11-14: Update the XML doc comment on BitMapLatLngBounds to mention
both bypass paths: note that because BitMapLatLngBounds is a record struct,
using with-expressions and using object initializers that assign init properties
both bypass the validating constructor (the instance is created first and then
init members are set), and state that validation is enforced when constructing
via the constructor new BitMapLatLngBounds(southWest, northEast); keep the
existing with-expression wording and add the init-property/object-initializer
explanation and the explicit constructor reminder.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts`:
- Around line 33-38: The ArcGIS provider in BitMapArcGis.ts silently ignores the
public options doubleClickZoom and keyboardNavigation; update the
navigation.actionMap block (and the similar block around lines 81-89) to either
apply those flags to ArcGIS equivalents or explicitly disable/reject them: read
o.doubleClickZoom and set the appropriate actionMap entry (e.g., map
doubleClickZoom to 'zoom' or null) and read o.keyboardNavigation to
enable/disable keyboard actions, or throw/log an explicit unsupported-option
error so callers aren’t silently ignored; modify the navigation.actionMap logic
that currently uses o.scrollWheelZoom and o.dragging to include
o.doubleClickZoom and o.keyboardNavigation handling.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapGlBase.ts`:
- Around line 105-107: The queued notify callback can run after teardown and
call a disposed .NET object; to fix, add a disposal guard: store a boolean
(e.g., this._isDisposed = false) on the BitMapGlBase instance, set it true in
your component teardown/dispose method, and update the notify lambda to check
the guard and dotnetObj before invoking (e.g., queueMicrotask(() => { if
(this._isDisposed || !dotnetObj) return;
dotnetObj.invokeMethodAsync('OnViewChanged', BitMapGlBase._readView(map)); }));
also ensure you remove the map listeners on dispose (map.off('moveend', notify);
map.off('zoomend', notify);) so no callbacks remain after disposal.

In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapOpenLayers.ts`:
- Around line 563-569: The dashArray parsing in BitMapOpenLayers._stroke
currently only splits on commas so whitespace-separated values like "4 2" become
a single value; update the split logic in BitMapOpenLayers._stroke (where it
builds lineDash from st.dashArray) to split on commas or whitespace (e.g. use
st.dashArray.split(/[,\s]+/)), then map each token with parseFloat and filter
out empty/NaN entries so both "4,2" and "4 2" parse to [4,2]; keep the rest of
the Stroke construction unchanged.
- Around line 662-664: The event handler for map.on('moveend') captures the
outer dn and can invoke a disposed handle inside queueMicrotask; snapshot the
.NET handle into a local const (e.g., const capturedDn = dn) before calling
queueMicrotask, then inside the microtask check capturedDn is non-null and call
capturedDn.invokeMethodAsync('OnViewChanged', BitMapOpenLayers._readView(s));
this ensures the microtask uses the captured handle and avoids invoking a
disposed dn.

---

Duplicate comments:
In `@src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss`:
- Line 7: The Sass import in extra-components.scss uses a filename with the
.scss extension which violates scss/load-partial-extension; update the import
statement that currently references "../Components/Map/BitMap.scss" to omit the
.scss extension (use "../Components/Map/BitMap") so the linter accepts the
partial import.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor`:
- Around line 3-5: Update the PageOutlet component's Description attribute to a
polished, grammatically correct string: replace Description="map component of
the bit BlazorUI components" with a properly cased sentence such as
Description="Map component of the Bit BlazorUI components." (edit the PageOutlet
element where Url="components/map" and Title="Map").

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor.cs`:
- Around line 772-804: The sample string example7CsharpCode is out of sync with
the real BuildAdvancedProvider behavior because the live BuildAdvancedProvider
resets advOverlayOn when rebuilding the provider but the displayed snippet does
not; update the example7CsharpCode snippet to show the same reset logic by
modifying the BuildAdvancedProvider code in the snippet to set advOverlayOn =
false (or the real reset behavior) when creating the new advProvider, ensuring
the displayed BuildAdvancedProvider matches the runtime method and keeps
advOverlayOn consistent after provider rebuilds.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7cdf6642-466b-4e81-aaf0-62efd2005353

📥 Commits

Reviewing files that changed from the base of the PR and between c39961b and 708c184.

⛔ Files ignored due to path filters (5)
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/layers-2x.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/layers.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-icon-2x.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-icon.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-shadow.png is excluded by !**/*.png
📒 Files selected for processing (41)
  • .gitignore
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapInteropErrorArgs.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLng.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLngBounds.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarker.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarkerDragEndArgs.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapProviderBase.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapTileOverlay.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapTooltipDirection.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapValidation.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapVectorPathStyle.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapViewState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/IBitMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitArcGisMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitAzureMapsMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitCesiumMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitLeafletMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapAzureMaps.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapCesium.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapGlBase.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapLeaflet.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapLibreMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapMapLibre.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapMapbox.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapOpenLayers.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapShared.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapboxMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitOpenLayersMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/leaflet-1.9.4.css
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/leaflet-1.9.4.js
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/openlayers/bit-map-ol-loader.js
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/MainLayout.razor.NavItems.cs
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/Map/BitMapTests.cs

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLngBounds.cs Outdated
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapGlBase.ts Outdated
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapOpenLayers.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 39 out of 46 changed files in this pull request and generated 4 comments.

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLng.cs
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarker.cs
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarker.cs
@msynk

msynk commented May 28, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

@msynk Sure, I'll re-review the PR now.

✅ Actions performed

Full review triggered.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 39 out of 46 changed files in this pull request and generated 3 comments.

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLng.cs
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarker.cs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitArcGisMapProvider.cs`:
- Around line 37-54: Trim BasemapId and ApiKey before validation and before
putting them into the payload: call Trim/TrimInvariant on BasemapId and ApiKey
at the start of the provider logic that performs validation (the checks using
BasemapId and ApiKey) and then use the trimmed values when setting
common["basemapId"] and common["apiKey"]; ensure string.Equals against "osm"
uses the trimmed BasemapId. This ensures inputs like " osm " are treated as
"osm" and payload/validation are consistent for GetCommonOptions and the Map
provider.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts`:
- Around line 61-65: Wrap the await view.when() call in a try/catch and, on
rejection, rollback the partially created state by removing
BitMapArcGis._maps[id] and tearing down the created MapView/state: call
view.destroy() (or view?.destroy?.()) and any state cleanup (remove layers,
remove event handlers wired by BitMapArcGis._wireEvents) so the stale instance
is not left registered; rethrow the error after cleanup so initialization still
fails upstream. Ensure you reference the same symbols:
BitMapArcGis._ensureScaleBar, BitMapArcGis._wireEvents, BitMapArcGis._maps[id],
and view.when() when making the change.
- Around line 108-117: The dispose method (BitMapArcGis.dispose) currently only
destroys the ArcGIS view but doesn't remove DOM event listeners added by
_applyInteractivity, leaving stale dblclick/keydown handlers attached to the
container; update _applyInteractivity to store the actual handler functions
(e.g., onDoubleClick/onKeyDown) on the map instance object
(BitMapArcGis._maps[id].containerHandlers or similar) when adding them with
addEventListener, and then in BitMapArcGis.dispose remove those listeners via
removeEventListener before destroying the view and deleting the map entry so the
container is fully cleaned up.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapCesium.ts`:
- Around line 260-266: The code in _applyImagery() currently always removes
imageryLayers.get(0) which can be a user overlay; change logic to track and
remove only the stored base layer (_baseImageryLayer) instead of unconditionally
removing index 0, initialize _baseImageryLayer in init() from the viewer's
initial base layer (when present) so subsequent calls to _applyImagery()
replace/remove that specific layer, and ensure addTileOverlay() adds overlays
without altering _baseImageryLayer.

In
`@src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor.cs`:
- Around line 875-898: Update the example5CsharpCode string so it exactly
mirrors the real SetTileProvider implementation: ensure the "carto" branch in
example5CsharpCode sets TileAttribution to "&copy; OSM &copy; CARTO" and
restore/add the TileAttribution property in the "topo" branch to match the live
demo's attribution (the same string used by the actual SetTileProvider for
BitLeafletMapProvider.TileAttribution). This keeps example5CsharpCode consistent
with the SetTileProvider method and preserves required map credits.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a7746b2b-0205-483e-9c79-881b680fc092

📥 Commits

Reviewing files that changed from the base of the PR and between c39961b and b68b140.

⛔ Files ignored due to path filters (5)
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/layers-2x.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/layers.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-icon-2x.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-icon.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-shadow.png is excluded by !**/*.png
📒 Files selected for processing (41)
  • .gitignore
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapInteropErrorArgs.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLng.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLngBounds.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarker.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarkerDragEndArgs.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapProviderBase.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapTileOverlay.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapTooltipDirection.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapValidation.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapVectorPathStyle.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapViewState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/IBitMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitArcGisMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitAzureMapsMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitCesiumMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitLeafletMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapAzureMaps.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapCesium.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapGlBase.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapLeaflet.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapLibreMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapMapLibre.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapMapbox.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapOpenLayers.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapShared.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapboxMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitOpenLayersMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/leaflet-1.9.4.css
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/leaflet-1.9.4.js
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/openlayers/bit-map-ol-loader.js
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/MainLayout.razor.NavItems.cs
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/Map/BitMapTests.cs

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitArcGisMapProvider.cs Outdated
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts Outdated
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapCesium.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 39 out of 46 changed files in this pull request and generated 5 comments.

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLng.cs
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLng.cs
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarker.cs
Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarker.cs
@msynk

msynk commented May 28, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai re-review

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

@msynk Sure, I'll re-review the PR now.

✅ Actions performed

Full review triggered.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts (1)

73-78: ⚠️ Potential issue | 🟠 Major

Restore the original tabindex in both cleanup paths.

_applyInteractivity() can persist __bmPrevTabIndex and force tabindex="-1", but the init-failure rollback and dispose() only remove listeners. After a failed init or provider swap, the container can stay non-focusable and the next map instance inherits broken keyboard access.

Suggested fix
             if (container) {
                 const view = s.view as any;
                 if (view.__bmDblClickHandler) {
                     try { container.removeEventListener('dblclick', view.__bmDblClickHandler, true); } catch { /* ignore */ }
                     view.__bmDblClickHandler = null;
                 }
                 if (view.__bmKeyHandler) {
                     try { container.removeEventListener('keydown', view.__bmKeyHandler, true); } catch { /* ignore */ }
                     view.__bmKeyHandler = null;
                 }
+                if (view.__bmPrevTabIndex !== undefined) {
+                    try {
+                        if (view.__bmPrevTabIndex === null) container.removeAttribute('tabindex');
+                        else container.setAttribute('tabindex', view.__bmPrevTabIndex);
+                    } catch { /* ignore */ }
+                    view.__bmPrevTabIndex = undefined;
+                }
             }

Apply the same reset in the view.when() rollback block above.

Also applies to: 134-145

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts`
around lines 73 - 78, The cleanup currently removes only event listeners
(dblHandler/keyHandler) but does not restore the previous tabindex set by
_applyInteractivity (stored in __bmPrevTabIndex), leaving the container
non-focusable after init failure or dispose; update both the view.when()
rollback block and the dispose() cleanup (the block that references dblHandler
and keyHandler) to read (view as any).__bmPrevTabIndex and if defined restore it
to element.tabIndex (or remove the tabindex attribute when it was originally
absent) so the original focusability is restored after rollback/dispose.
src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapCesium.ts (1)

657-665: ⚠️ Potential issue | 🟠 Major

Guard the queued OnViewChanged invoke after disposal.

Capturing view fixed the destroyed-view read, but the microtask still unconditionally calls the captured .NET handle. If dispose() runs after _notifyView() schedules the microtask, this can still reject against a disposed handle.

Suggested fix
         private static _notifyView(s: any) {
             if (!s.dotnetObj) return;
             // Capture the view snapshot synchronously. dispose() can destroy s.viewer
             // and null s.dotnetObj before this microtask runs, so deferring _readView
             // would risk reading from a destroyed Cesium Viewer. We snapshot the
             // dotnet handle and the view payload here while everything is still alive.
             const dotnet = s.dotnetObj;
             const view = BitMapCesium._readView(s);
-            queueMicrotask(() => dotnet.invokeMethodAsync('OnViewChanged', view));
+            queueMicrotask(() => {
+                if (s.dotnetObj !== dotnet) return;
+                void dotnet.invokeMethodAsync('OnViewChanged', view).catch(() => {});
+            });
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapCesium.ts`
around lines 657 - 665, The microtask unconditionally calls the captured .NET
handle even if dispose() ran later; modify _notifyView to capture both dotnet
and the source object (s) and, inside the queued microtask, verify the handle is
still current (e.g., if (s.dotnetObj === dotnet)
dotnet.invokeMethodAsync('OnViewChanged', view)) or otherwise skip the call;
alternatively wrap the invokeMethodAsync in a try/catch and silently ignore
errors from a disposed handle—update the _notifyView implementation (references:
_notifyView, dotnetObj, _readView, OnViewChanged, dispose) accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor.cs`:
- Around line 203-205: The code currently updates the in-memory replay
dictionaries (_markerState, _vectorState, _tileOverlayState) before calling
SafeInvokeAsync (e.g. BitMapAddMarker via JsObject in AddMarker), which can hide
interop failures; change each affected method so the dictionary mutation is
performed only after SafeInvokeAsync completes successfully (await the call and
then add/remove/clear the entry), or if you prefer to keep the pre-mutation,
wrap SafeInvokeAsync in try/catch and roll back the dictionary change on any
exception; apply this pattern consistently to all methods touching
_markerState/_vectorState/_tileOverlayState (the Add*/Remove*/Clear* flows) so
ReplayStateOnProviderSwap remains in sync with the real map.

---

Duplicate comments:
In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts`:
- Around line 73-78: The cleanup currently removes only event listeners
(dblHandler/keyHandler) but does not restore the previous tabindex set by
_applyInteractivity (stored in __bmPrevTabIndex), leaving the container
non-focusable after init failure or dispose; update both the view.when()
rollback block and the dispose() cleanup (the block that references dblHandler
and keyHandler) to read (view as any).__bmPrevTabIndex and if defined restore it
to element.tabIndex (or remove the tabindex attribute when it was originally
absent) so the original focusability is restored after rollback/dispose.

In `@src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapCesium.ts`:
- Around line 657-665: The microtask unconditionally calls the captured .NET
handle even if dispose() ran later; modify _notifyView to capture both dotnet
and the source object (s) and, inside the queued microtask, verify the handle is
still current (e.g., if (s.dotnetObj === dotnet)
dotnet.invokeMethodAsync('OnViewChanged', view)) or otherwise skip the call;
alternatively wrap the invokeMethodAsync in a try/catch and silently ignore
errors from a disposed handle—update the _notifyView implementation (references:
_notifyView, dotnetObj, _readView, OnViewChanged, dispose) accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5177733e-e49d-4063-820f-066ee8bb8834

📥 Commits

Reviewing files that changed from the base of the PR and between c39961b and c41d99f.

⛔ Files ignored due to path filters (5)
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/layers-2x.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/layers.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-icon-2x.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-icon.png is excluded by !**/*.png
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/images/marker-shadow.png is excluded by !**/*.png
📒 Files selected for processing (41)
  • .gitignore
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapInteropErrorArgs.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapJsRuntimeExtensions.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLng.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapLatLngBounds.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarker.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapMarkerDragEndArgs.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapProviderBase.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapTileOverlay.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapTooltipDirection.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapValidation.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapVectorPathStyle.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMapViewState.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/IBitMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitArcGisMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitAzureMapsMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitCesiumMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitLeafletMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapArcGis.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapAzureMaps.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapCesium.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapGlBase.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapLeaflet.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapLibreMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapMapLibre.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapMapbox.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapOpenLayers.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapShared.ts
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitMapboxMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/Providers/BitOpenLayersMapProvider.cs
  • src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-components.scss
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/leaflet-1.9.4.css
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/leaflet-1.9.4.js
  • src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/openlayers/bit-map-ol-loader.js
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/Map/BitMapDemo.razor.cs
  • src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/MainLayout.razor.NavItems.cs
  • src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Extras/Map/BitMapTests.cs

Comment thread src/BlazorUI/Bit.BlazorUI.Extras/Components/Map/BitMap.razor.cs Outdated
@msynk
msynk merged commit c1bc10c into bitfoundation:develop May 29, 2026
3 checks passed
@msynk
msynk deleted the 10110-blazorui-map-component branch May 29, 2026 07:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The BlazorUI library is missing a Map component

3 participants